/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufc.quixada.adrs.grafico;

import br.ufc.quixada.adrs.model.RelatorioQualitativoResult;
import br.ufc.quixada.adrs.util.Msg;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.List;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.AbstractCategoryItemLabelGenerator;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.ui.TextAnchor;

/**
 *
 * @author Escritorio projetos
 */
public class ADRSPercentBarChart {

    private String title;
    private String labelXAxis;
    private String labelYAxis;
    private String graphicType;

    public ADRSPercentBarChart(String _title, String _labelXAxis, String _labelYAxiss, String _graphicType) {

        this.title = _title;
        this.labelXAxis = _labelXAxis;
        this.labelYAxis = _labelYAxiss;
        this.graphicType = _graphicType;
    }

    /**
     *Classe utilizada para customizar o label das barras do gráfico.
     */
    static class PercentLabelGenerator extends AbstractCategoryItemLabelGenerator
            implements CategoryItemLabelGenerator {

        /**
         * Cria um novo gerador de label que mostra os labels acrescidos do caractere %
         */
        public PercentLabelGenerator() {
            super("", NumberFormat.getInstance());
        }

        /**
         * Gera um label para o item especificado. O label é tipicamente uma versão formatada do valor numérico.
         * Mas, qualquer texto pode ser usado.
         * @param dataset  O dataset (<code>null</code> Não permitido).
         * @param series  o índice da serie.
         * @param category  o índice da categoria.
         *
         * @return o label (possivelmente <code>null</code>).
         */
        public String generateLabel(CategoryDataset dataset,
                int series,
                int category) {
            String result = null;
            Number value = dataset.getValue(series, category);
            if (value != null) {
                result = value.toString() + " %";  // could apply formatting here
            }
            return result;

        }
    }

    /**
     *Classe utilizada para customizar o label das barras do gráfico. Mostra o valor numérico e a porcenttagem correspondente.
     */
    static class CalulatePercentLabelGenerator extends AbstractCategoryItemLabelGenerator
            implements CategoryItemLabelGenerator {

        CategoryDataset datasetAux = null;

        /**
         * Cria um novo gerador de label que mostra os labels com acrescidos do caractere %
         */
        public CalulatePercentLabelGenerator(CategoryDataset _dataset) {
            super("", NumberFormat.getInstance());
            datasetAux = _dataset;
        }

        /**
         * Gera um label para o item especificado. O label é tipicamente uma versão formatada do valor numérico.
         * Mas, qualquer texto pode ser usado.
         * @param dataset  O dataset (<code>null</code> Não permitido).
         * @param series  o índice da serie.
         * @param category  o índice da categoria.
         *
         * @return o label (possivelmente <code>null</code>).
         */
        public String generateLabel(CategoryDataset dataset,
                int series,
                int category) {

            String result = null;
            Number value = dataset.getValue(series, category);
            Number percentValue = datasetAux.getValue(series, category);

            if (value != null) {
                result = value.toString() + " (" + percentValue.toString() + " %)";  // could apply formatting here
            }
            return result;

        }
    }

    /**
     * Creates a sample dataset.
     *
     * @return A sample dataset.
     */
    public JFreeChart createChart(CategoryDataset dataset, CategoryDataset datasetAux, PlotOrientation plotOrientation) {
        // create the chart...
        JFreeChart chart = ChartFactory.createBarChart3D(
                title, // chart title
                labelXAxis, // domain axis label
                labelYAxis, // range axis label
                dataset, // data
                plotOrientation, // orientation
                true, // include legend
                true,
                false);
//        chart.addSubtitle(new TextTitle(
//                "Fonte: Sistema ADRS",
//                new Font("Dialog", Font.ITALIC, 10)));
        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
        BarRenderer renderer = (BarRenderer) plot.getRenderer();

        renderer.setItemLabelAnchorOffset(6.0);
        renderer.setBaseItemLabelsVisible(true);
        renderer.setBaseItemLabelGenerator(
                new StandardCategoryItemLabelGenerator());
        renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator(
                "{0}, {1}) = {4} per 100,000", new DecimalFormat("0")));
//       Por default, quando os numeros não podem ser exibidos dentro da barra eles são ocultados.
//       Para exibir, esses numeros devemos criar uma posição que os eleva ao topo. em seguida usamos//        o metodo setPositiveItemLabelPositionFallback(position) para elevar o label para o topo.
        ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
        renderer.setPositiveItemLabelPositionFallback(position);
        renderer.setBaseItemLabelFont(new Font(Font.SANS_SERIF , Font.PLAIN, 11));
        renderer.setMinimumBarLength(0.10);
        renderer.setMaximumBarWidth(0.10);
        renderer.setDrawBarOutline(true);
        renderer.setBaseOutlinePaint(Color.white);
        renderer.setBaseOutlineStroke(new BasicStroke(0.5f));
        CategoryAxis categoryAxis = plot.getDomainAxis();
        //categoryAxis.setItemMargin(0.20);
        categoryAxis.setUpperMargin(0.02);
        categoryAxis.setLowerMargin(0.02);
//        //categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
        categoryAxis.setMaximumCategoryLabelLines(100);
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
//        rangeAxis.setUpperMargin(0.10);
//        renderer.setMaximumBarWidth(0.2);
        renderer.setItemMargin(0.05);

        if (graphicType.equals(Msg.GRAPHIC_QL_AVALIACAO_PORCENTAGEM)) {
            List seriesName = dataset.getRowKeys();
            for (int i = 0; i < seriesName.size(); i++) {
                String serie = (String) seriesName.get(i);
                if (serie.equalsIgnoreCase(RelatorioQualitativoResult.RESPOSTA_SIM)) {
                    renderer.setSeriesPaint(i, Color.BLUE);
                } else if (serie.equalsIgnoreCase(RelatorioQualitativoResult.RESPOSTA_SIM_ADEQUADAMENTE)) {
                    renderer.setSeriesPaint(i, Color.GREEN);
                } else if (serie.equalsIgnoreCase(RelatorioQualitativoResult.RESPOSTA_NAO)) {
                    renderer.setSeriesPaint(i, Color.RED);
                } else if (serie.equalsIgnoreCase(RelatorioQualitativoResult.RESPOSTA_NAO_RESPONDIDO)) {
                    renderer.setSeriesPaint(i, Color.GRAY);
                }
            }
            renderer.setBaseItemLabelGenerator(new PercentLabelGenerator());
            //Mostra eixo y com valores de 0 a 100% a exclusão dessas 2 linhas deixa os numeros no intervalo de 0.0 a 0.1
//            rangeAxis.setNumberFormatOverride(new DecimalFormat("0%"));
        }
        if (graphicType.equals(Msg.GRAPHIC_QL_TIPO_RESPOSTA_PORC_QUANTIDADE)) {
            List seriesName = dataset.getRowKeys();
            for (int i = 0; i < seriesName.size(); i++) {
                String serie = (String) seriesName.get(i);
                if (serie.equalsIgnoreCase(RelatorioQualitativoResult.RESPOSTA_SIM)) {
                    renderer.setSeriesPaint(i, Color.BLUE);
                } else if (serie.equalsIgnoreCase(RelatorioQualitativoResult.RESPOSTA_SIM_ADEQUADAMENTE)) {
                    renderer.setSeriesPaint(i, Color.GREEN);
                } else if (serie.equalsIgnoreCase(RelatorioQualitativoResult.RESPOSTA_NAO)) {
                    renderer.setSeriesPaint(i, Color.RED);
                } else if (serie.equalsIgnoreCase(RelatorioQualitativoResult.RESPOSTA_NAO_RESPONDIDO)) {
                    renderer.setSeriesPaint(i, Color.GRAY);
                }
            }
            renderer.setBaseItemLabelGenerator(new CalulatePercentLabelGenerator(datasetAux));
            //Mostra eixo y com valores de 0 a 100% a exclusão dessas 2 linhas deixa os numeros no intervalo de 0.0 a 0.1
//            rangeAxis.setNumberFormatOverride(new DecimalFormat("0%"));
        }


        renderer.setBaseSeriesVisible(true);


        return chart;

    }
}
